package cn.edu.jxau.core.service;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;

import cn.edu.jxau.core.exception.ServiceException;
import cn.edu.jxau.core.util.DateUtils;
import cn.edu.jxau.core.util.StringUtil;
import cn.edu.jxau.core.util.upload.FileUpload;
import cn.edu.jxau.framework.dao.core.Session;
import cn.edu.jxau.framework.dao.core.sqlSessionFactory;

/**
 * 光谱分析报告
 * 统计分析报告
 * ReportService
 * @author zclong 2017年8月31日
 */
public class ReportService extends ServiceSupport {

    //日志信息
    private Logger logger =  LoggerFactory.getLogger(ReportService.class);
    
    public ReportService() {
    }

    public ReportService(String view, Map<String, Object[]> params, Map<String, Object> data) throws ServiceException {
        /**
         * view service.xml中的name和视图对应
         * params request入口的参数数组
         * data 返回给Servlet的出口参数
         */
        super(view, params, data);
        execute(view, params, data); // 执行业务
    }
    
    /**
     * 生成光谱分析报告
     * @zclong
     * @2017年8月27日
     * @ReturnType: void
     * @param params
     * @param data
     */
    protected void addReport(Map<String, Object[]> params, Map<String, Object> data) {
        Map<String, Object> param = new HashMap<String, Object>(); //用来封装传递给数据库的参数
        List<HashMap<String, Object>> datas = new ArrayList(); // 用来接收数据库返回回来的
        
    }

    /**
     * 查看光谱分析报告
     * @zclong
     * @2017年8月27日
     * @ReturnType: void
     * @param params
     * @param data
     */
   /* protected void queryReport(Map<String, Object[]> params, Map<String, Object> data) {
        Map<String, Object> param = new HashMap<String, Object>(); //用来封装传递给数据库的参数
        List<HashMap<String, Object>> datas = new ArrayList(); // 用来接收数据库返回回来的

        String userID = getParamStringValue(params, "userID", 0); // 获取用户id
        String spectruminfoID = getParamStringValue(params, "spectruminfoID", 0); // 获取要分析的光谱的主键编号
        
        try {
            Session session = sqlSessionFactory.getInstance().getSession();
            param.put("spectruminfoID", spectruminfoID);
            param.put("userID", userID);
            session.execute("queryReport", param, datas);
            if (null == datas || datas.isEmpty()) {
                data.put("error_msg", "未进行光谱分析，暂无光谱报告！");
                data.put("result", FAILED);
                return;
            } else {
                data.put("report", datas.get(0));
                //得到被检测物编号，进而查询数据库得到被检测物名称和被检测物内容
                int detectedID = (int) datas.get(0).get("detectedID");
                int reportID = (int) datas.get(0).get("reportID");
                param.clear();
                datas.clear();
                param.put("detectedID", detectedID);
                session.execute("queryDetected", param, datas); // 根据被检测物编号查询对应的被检测物
                if (null == datas || datas.isEmpty()) {
                    data.put("error_msg", "数据错误，请重试！");
                    data.put("result", FAILED);
                    return;
                } else {
                    data.put("detected", datas.get(0));
                    int classifyID = (int) datas.get(0).get("classifyID");
                    param.clear();
                    datas.clear();
                    param.put("classifyID", classifyID);
                    session.execute("querydetectedType", param, datas); // 
                    data.put("secondaryClassification", datas.get(0).get("secondaryClassification")); //被检测物分类
                    
                    param.clear();
                    datas.clear();
                    param.put("reportID", reportID);
                    session.execute("queryContentDetail", param, datas); // 根据光谱报告编号查询检测物质细节表
                    if (null == datas || datas.isEmpty()) {
                        data.put("error_msg", "数据错误，请重试！");
                        data.put("result", FAILED);
                        return;
                    } else {
                        data.put("contentDetail", datas);
                        data.put("result", SUCCESS);
                        logger.debug(JSON.toJSONString(data));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }*/
    
    protected void queryReport(Map<String, Object[]> params, Map<String, Object> data) {
        Map<String, Object> param = new HashMap<String, Object>(); //用来封装传递给数据库的参数
        List<HashMap<String, Object>> datas = new ArrayList();  // 用来接收数据库返回回来的

        String userID = getParamStringValue(params, "userID", 0); // 获取用户id
        String spectruminfoID = getParamStringValue(params, "spectruminfoID", 0); // 获取要分析的光谱的主键编号
        try {
            Session session = sqlSessionFactory.getInstance().getSession();
            param.put("spectruminfoID", spectruminfoID);
            param.put("userID", userID);
            session.execute("queryReport", param, datas);
            if (null == datas || datas.isEmpty()) {
                data.put("error_msg", "未进行光谱分析，暂无光谱报告！");
                data.put("result", FAILED);
                return;
            } else {
                data.put("report", datas.get(0));
                //得到被检测物编号，进而查询数据库得到被检测物名称和被检测物内容
                int detectedID = (int) datas.get(0).get("detectedID");
                int reportID = (int) datas.get(0).get("reportID");
                param.clear();
                datas.clear();
                param.put("detectedID", detectedID);
                session.execute("queryDetected", param, datas); // 根据被检测物编号查询对应的被检测物
                if (null == datas || datas.isEmpty()) {
                    data.put("error_msg", "数据错误，请重试！");
                    data.put("result", FAILED);
                    return;
                } else {
                    data.put("detected", datas.get(0));
                    param.clear();
                    datas.clear();
                    param.put("reportID", reportID);
                    session.execute("queryContentDetail", param, datas); // 根据光谱报告编号查询检测物质细节表
                    if (null == datas || datas.isEmpty()) {
                        data.put("error_msg", "数据错误，请重试！");
                        data.put("result", FAILED);
                        return;
                    } else {
                        data.put("contentDetail", datas);
                        data.put("result", SUCCESS);
                        logger.debug(JSON.toJSONString(data));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 统计分析前进行查询出用户信息和检测内容，所检测地区
     * @zclong
     * @2017年8月28日
     * @ReturnType: void
     * @param params
     * @param data
     */
    @SuppressWarnings({ "unused", "unchecked" })
    private void loadStatistical(Map<String, Object[]> params, Map<String, Object> data) {
        Map<String, Object> param = new HashMap<String, Object>(); //用来封装传递给数据库的参数
        List<HashMap<String, Object>> datas = new ArrayList(); // 用来接收数据库返回回来的

        //获取参数
        String userID = getParamStringValue(params, "userID", 0);

        //通过userID查询出该用户信息和分析报告
        try {
            Session session = sqlSessionFactory.getInstance().getSession();
            param.put("userID", userID);
            session.execute("queryReportByUserID", param, datas);
            if (null == datas || datas.isEmpty()) {
                data.put("error_msg", "暂无已分析的光谱，无法进行统计分析！");
                data.put("result", FAILED);
                return;
            } else {
                //data.put("reports", datas);
                datas.clear();
                session.execute("queryReportContentDetail", param, datas);
                data.put("reportContentDetails", datas); // 拿到所有的内容
               
                List<String> contents = new ArrayList(); // 存储所有检测内容
                List<String> categoryOrigins = new ArrayList(); // 存储所有检测地区
                List<Integer> statisticsTime = new ArrayList(); // 存储所有统计时间，四个星期
                for (int i = 1; i <= 4; i++) {
                    statisticsTime.add(i);
                }
                for (HashMap<String, Object> content : datas) {
                    contents.add((String) content.get("name"));
                    categoryOrigins.add((String) content.get("categoryOrigin"));
                }
                //调用去除重复数据方法
                contents = StringUtil.removeDuplicate(contents); // 得到所有检测内容
                categoryOrigins = StringUtil.removeDuplicate(categoryOrigins); // 得到所有检测地区
                data.put("contents", contents);
                data.put("categoryOrigins", categoryOrigins);
                data.put("statisticsTime", statisticsTime);
                data.put("result", SUCCESS);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 下载光谱图片
     * @zclong
     * @2017年9月3日
     * @ReturnType: void
     * @param params
     * @param data
     */
    private void downSpectrumPicture(Map<String, Object[]> params, Map<String, Object> data) {
        Map<String, Object> param = new HashMap<String, Object>(); //用来封装传递给数据库的参数
        List<HashMap<String, Object>> datas = new ArrayList(); // 用来接收数据库返回回来的
        
        String spectrumPicture = getParamStringValue(params, "spectrumPicture", 0); // 图片路径
        
        String base = FileUpload.getBaseABSPath();
        File file = new File(base,spectrumPicture);
        data.put("file", file);

        if (file.exists()) {
            data.put("result", SUCCESS);
        }else {
            data.put("result", FAILED);
        }
        
    }
    
    /**
     * 统计分析
     * @zclong
     * @2017年8月28日
     * @ReturnType: void
     * @param params
     * @param data
     */
    @SuppressWarnings("unused")
    private void statisticalAnalysis(Map<String, Object[]> params, Map<String, Object> data) {
        Map<String, Object> param = new HashMap<String, Object>(); //用来封装传递给数据库的参数
        List<HashMap<String, Object>> datas = new ArrayList(); // 用来接收数据库返回回来的
        
        List<HashMap<String, Object>> analysisDatas = new ArrayList(); // 用来返回给前台

        //获取参数
        String userID = getParamStringValue(params, "userID", 0).trim();
        // 获取分析条件
        String analysisConditions = getParamStringValue(params, "contentsCondition", 0); // 检测内容
        String categoryOriginsCondition = getParamStringValue(params, "categoryOriginsCondition", 0); // 所检测地区
        String timeCondition = getParamStringValue(params, "timeCondition", 0); // 统计时间
        String startDate = getParamStringValue(params, "startDate", 0); // 统计分析初始时间
        String endDate = getParamStringValue(params, "endDate", 0); // 统计分析结束时间
        
        logger.debug(analysisConditions + "===" + categoryOriginsCondition + "==" + timeCondition + "==" + startDate + "==" + endDate);
        // 判断查询条件是否为空
        if(StringUtil.isEmpty(analysisConditions) && StringUtil.isEmpty(categoryOriginsCondition) && StringUtil.isEmpty(timeCondition) && StringUtil.isEmpty(startDate) && StringUtil.isEmpty(endDate)) {
            data.put("error_msg", "查询错误");
            data.put("result", FAILED);
            return;
        }

        try {
            Session session = sqlSessionFactory.getInstance().getSession();
            param.put("userID", userID);
            session.execute("queryReportContentDetail", param, datas); // 拿到所有的内容
            if(null != datas && datas.isEmpty()) {
                data.put("error_msg", "查询错误");
                data.put("result", FAILED);
                return;
            } else {
                List<String> detecteds = new ArrayList(); // 存储所有被检测物
              //根据条件获取相应的数据
                if(!StringUtil.isEmpty(analysisConditions) && StringUtil.isEmpty(categoryOriginsCondition) && StringUtil.isEmpty(timeCondition) && StringUtil.isEmpty(startDate) && StringUtil.isEmpty(endDate)) {
                    /*
                     * 仅进行统计分析的条件为：检测内容
                     */
                    String condition = "name";
                    getAnalysisDatas(datas, analysisDatas, analysisConditions, condition);
                } else if(StringUtil.isEmpty(analysisConditions) && !StringUtil.isEmpty(categoryOriginsCondition) && StringUtil.isEmpty(timeCondition) && StringUtil.isEmpty(startDate) && StringUtil.isEmpty(endDate)) {
                    /*
                     * 仅进行统计分析的条件为：检测地区
                     */
                    String condition = "categoryOrigin";
                    getAnalysisDatas(datas, analysisDatas, categoryOriginsCondition, condition);
                } else if(!StringUtil.isEmpty(analysisConditions) && !StringUtil.isEmpty(categoryOriginsCondition) && StringUtil.isEmpty(timeCondition) && StringUtil.isEmpty(startDate) && StringUtil.isEmpty(endDate)) {
                    /*
                     * 进行统计分析的条件为： 检测内容和检测地区
                     */
                    String condition = "name";
                    getAnalysisDatas(datas, analysisDatas, analysisConditions, condition);
                    condition = "categoryOrigin";
                    List<HashMap<String, Object>> datasObject = new ArrayList(); // 用来接收数据库返回回来的
                    datasObject.addAll(analysisDatas);
                    analysisDatas.clear(); // 用来返回给前台
                    getAnalysisDatas(datasObject, analysisDatas, categoryOriginsCondition, condition);
                } else if(StringUtil.isEmpty(analysisConditions) && StringUtil.isEmpty(categoryOriginsCondition) && !StringUtil.isEmpty(timeCondition) && StringUtil.isEmpty(startDate) && StringUtil.isEmpty(endDate)) {
                    /*
                     * 进行统计分析的条件为：统计时间
                     */
                    String condition = "createTime";
                    getTimeDatas(datas, analysisDatas, condition, Integer.parseInt(timeCondition));
                } else if(!StringUtil.isEmpty(analysisConditions) && StringUtil.isEmpty(categoryOriginsCondition) && !StringUtil.isEmpty(timeCondition) && StringUtil.isEmpty(startDate) && StringUtil.isEmpty(endDate)) {
                    /*
                     * 进行统计分析的条件为：统计时间和检测内容
                     */
                    String condition = "name";
                    getAnalysisDatas(datas, analysisDatas, analysisConditions, condition);
                    condition = "createTime";
                    List<HashMap<String, Object>> datasObject = new ArrayList(); // 用来接收数据库返回回来的
                    datasObject.addAll(analysisDatas);
                    analysisDatas.clear(); // 用来返回给前台
                    getTimeDatas(datasObject, analysisDatas, condition, Integer.parseInt(timeCondition));
                } else if(StringUtil.isEmpty(analysisConditions) && !StringUtil.isEmpty(categoryOriginsCondition) && !StringUtil.isEmpty(timeCondition) && StringUtil.isEmpty(startDate) && StringUtil.isEmpty(endDate)) {
                    /*
                     * 进行统计分析的条件为：统计时间和检测地区
                     */
                    String condition = "categoryOrigin";
                    getAnalysisDatas(datas, analysisDatas, categoryOriginsCondition, condition);
                    condition = "createTime";
                    List<HashMap<String, Object>> datasObject = new ArrayList(); // 用来接收数据库返回回来的
                    datasObject.addAll(analysisDatas);
                    analysisDatas.clear(); // 用来返回给前台
                    getTimeDatas(datasObject, analysisDatas, condition, Integer.parseInt(timeCondition));
                }else if(StringUtil.isEmpty(analysisConditions) && StringUtil.isEmpty(categoryOriginsCondition) && StringUtil.isEmpty(timeCondition) && !StringUtil.isEmpty(startDate) && !StringUtil.isEmpty(endDate)) {
                    /*
                     * 进行统计分析的条件为：统计时间区域段
                     */
                    String condition = "createTime";
                    getTimeZoneDatas(datas, analysisDatas, condition, startDate, endDate);
                } else if(!StringUtil.isEmpty(analysisConditions) && StringUtil.isEmpty(categoryOriginsCondition) && StringUtil.isEmpty(timeCondition) && !StringUtil.isEmpty(startDate) && !StringUtil.isEmpty(endDate)) {
                    /*
                     * 进行统计分析的条件为：统计时间区域段和检测内容
                     */
                    String condition = "name";
                    getAnalysisDatas(datas, analysisDatas, analysisConditions, condition);
                    condition = "createTime";
                    List<HashMap<String, Object>> datasObject = new ArrayList(); // 用来接收数据库返回回来的
                    datasObject.addAll(analysisDatas);
                    analysisDatas.clear(); // 用来返回给前台
                    getTimeZoneDatas(datasObject, analysisDatas, condition, startDate, endDate);
                } else if(StringUtil.isEmpty(analysisConditions) && !StringUtil.isEmpty(categoryOriginsCondition) && StringUtil.isEmpty(startDate) && !StringUtil.isEmpty(startDate) && !StringUtil.isEmpty(endDate)) {
                    /*
                     * 进行统计分析的条件为：统计时间区域段和检测地区
                     */
                    String condition = "categoryOrigin";
                    getAnalysisDatas(datas, analysisDatas, categoryOriginsCondition, condition);
                    condition = "createTime";
                    List<HashMap<String, Object>> datasObject = new ArrayList(); // 用来接收数据库返回回来的
                    datasObject.addAll(analysisDatas);
                    analysisDatas.clear(); // 用来返回给前台
                    getTimeZoneDatas(datasObject, analysisDatas, condition, startDate, endDate);
                } else if(!StringUtil.isEmpty(analysisConditions) && !StringUtil.isEmpty(categoryOriginsCondition) && !StringUtil.isEmpty(timeCondition) && StringUtil.isEmpty(startDate) && StringUtil.isEmpty(endDate)) {
                    /*
                     * 进行统计分析的条件为：统计时间和检测内容和检测地区
                     */
                    String condition = "name";
                    getAnalysisDatas(datas, analysisDatas, analysisConditions, condition);
                    condition = "categoryOrigin";
                    List<HashMap<String, Object>> datasObject = new ArrayList(); // 用来接收数据库返回回来的
                    datasObject.addAll(analysisDatas);
                    analysisDatas.clear(); // 用来返回给前台
                    getAnalysisDatas(datasObject, analysisDatas, categoryOriginsCondition, condition);
                    datasObject.clear();
                    datasObject.addAll(analysisDatas);
                    analysisDatas.clear(); // 用来返回给前台
                    condition = "createTime";
                    getTimeDatas(datasObject, analysisDatas, condition, Integer.parseInt(timeCondition));
                } else if(!StringUtil.isEmpty(analysisConditions) && !StringUtil.isEmpty(categoryOriginsCondition) && StringUtil.isEmpty(timeCondition) && !StringUtil.isEmpty(startDate) && !StringUtil.isEmpty(endDate)) {
                    /*
                     * 进行统计分析的条件为：统计时间区域段和检测内容和检测地区
                     */
                    String condition = "name";
                    getAnalysisDatas(datas, analysisDatas, analysisConditions, condition);
                    condition = "categoryOrigin";
                    List<HashMap<String, Object>> datasObject = new ArrayList(); // 用来接收数据库返回回来的
                    datasObject.addAll(analysisDatas);
                    analysisDatas.clear(); // 用来返回给前台
                    getAnalysisDatas(datasObject, analysisDatas, categoryOriginsCondition, condition);
                    datasObject.clear();
                    datasObject.addAll(analysisDatas);
                    analysisDatas.clear(); // 用来返回给前台
                    condition = "createTime";
                    getTimeZoneDatas(datasObject, analysisDatas, condition, startDate, endDate);
                }
                
                
                for (HashMap<String, Object> analysisData : analysisDatas) {
                    detecteds.add((String) analysisData.get("detectedName")); // 保存被检测物
                }
                //把detecteds中的值赋给Object
                List<String> object = new ArrayList(); 
                object.addAll(detecteds);
                
                //计算出被检测物的检测总数
                Map<Object, Object> detectedsMap = StringUtil.mapDuplicate(detecteds); // 得到map集合
                
                //计算出被检测物的合格数
                Map<Object, Object> regularsMap = StringUtil.regularDuplicate(analysisDatas, StringUtil.removeDuplicate(object), 0);

                // 进过处理后获得最终结果，合格数regularCount=0, 被检测物detectedObject=烤肉, 合格率proportion=0.00%, 检测总数count=2
                HashMap<String, Object> resultDatas = StringUtil.resultDatas(detectedsMap, regularsMap);
                data.put("resultDatas", resultDatas);
                data.put("result", SUCCESS);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        data.put("reportContentDetails", datas); // 拿到所有的内容
    }

    /**
     * 根据条件获取相应的数据
     * @zclong
     * @2017年8月30日
     * @ReturnType: void
     * @param datas 数据库返回回来的全部数据
     * @param analysisDatas // 存储经过筛选后的数据
     * @param analysisConditions // 前台的分析条件
     * @param condition // 筛选的条件
     */
    private void getAnalysisDatas(List<HashMap<String, Object>> datas, List<HashMap<String, Object>> analysisDatas,
            String analysisConditions, String condition) {
        for (HashMap<String, Object> datasDetected : datas) {
            String detected = (String) datasDetected.get(condition); // 根据前台传过来的分析条件获取相应的被检测物
            if(analysisConditions.equals(detected)) {
                analysisDatas.add(datasDetected);
            }
        }
    }

    /**
     * 根据时间获取相应的数据
     * @zclong
     * @2017年8月30日
     * @ReturnType: void
     * @param datas 数据库返回回来的全部数据
     * @param analysisDatas // 存储经过筛选后的数据
     * @param condition // 筛选的条件
     * @param timeCondition // 进行统计分析的时间段
     */
    @SuppressWarnings("unused")
    private void getTimeDatas(List<HashMap<String, Object>> datas, List<HashMap<String, Object>> analysisDatas,
            String condition, int timeCondition) {
        String time = DateUtils.getWeekAgoTime(timeCondition); // 获得一周前的时间
        for (HashMap<String, Object> datasDetected : datas) {
            String detected = (String) datasDetected.get(condition).toString(); // 根据前台传过来的分析条件获取相应的被检测物
            if(time.compareTo(detected) < 0) {
                analysisDatas.add(datasDetected);
            }
        }
    }
    
    /**
     * 根据时间区域获取相应的数据
     * @zclong
     * @2017年8月30日
     * @ReturnType: void
     * @param datas 数据库返回回来的全部数据
     * @param analysisDatas // 存储经过筛选后的数据
     * @param condition // 筛选的条件
     * @param timeCondition // 进行统计分析的时间段
     */
    @SuppressWarnings("unused")
    private void getTimeZoneDatas(List<HashMap<String, Object>> datas, List<HashMap<String, Object>> analysisDatas,
            String condition, String startDate, String endDate) {
        for (HashMap<String, Object> datasDetected : datas) {
            String detected = DateUtils.getFormatTime(datasDetected.get(condition)); // 根据前台传过来的分析条件获取相应的被检测物
            if(startDate.compareTo(detected) <= 0 && endDate.compareTo(detected) >= 0) {
                analysisDatas.add(datasDetected);
            }
        }
    }
}
